//
// Game.cpp for nibbler in /home/lefebv_w//workspace/cpp/nibbler/googleCode
// 
// Made by damien lefebvre
// Login   <lefebv_w@epitech.net>
// 
// Started on  Thu Mar 14 21:10:42 2013 damien lefebvre
// Last update Sun Mar 24 22:01:54 2013 damien lefebvre
//

#include	"Game.hh"

Game::Game(IGraphicLibrary & graph, std::vector< std::vector<char> > const & map)
  : m_graph(graph), m_size_x(map.size()), m_size_y(map[0].size()), m_frame(0), m_snake(m_size_x / 2, m_size_y / 2, 4), m_score(m_size_y), m_endOfGame(false), m_quit(false), m_pause(false)
{
  creatGameMap(map);
  m_bonus.initialize(0, m_map, m_snake);
}

Game::Game(IGraphicLibrary & graph, unsigned int size_x, unsigned int size_y)
  : m_graph(graph), m_size_x(size_x), m_size_y(size_y), m_frame(0), m_snake(m_size_x / 2, m_size_y / 2, 4),
    m_score(m_size_y), m_endOfGame(false), m_quit(false), m_pause(false)
{
  std::vector< std::vector<char> >	map;

  for (unsigned int i = 0; i < size_x; i++)
    {
      map.push_back(std::vector<char>());
      for (unsigned int j = 0; j < size_y; j++)
	{
	  if (i == 0 || i == size_x - 1 || j == 0 || j == size_y - 1)
	    map[i].push_back(CHAR_WALL);
	  else
	    map[i].push_back(CHAR_EMPTY);
	}
    }
  creatGameMap(map);
  m_bonus.initialize(0, m_map, m_snake);
}

void		Game::creatGameMap(std::vector< std::vector<char> > const & map)
{
  IGraphicLibrary::e_TypeOfCase		t;
  IGraphicLibrary::e_ListOfImage	img;

  for (unsigned int i = 0; i < map.size(); i++)
    {
      m_map.push_back(std::vector<Case *>());
      for (unsigned int j = 0; j < map[i].size(); j++)
	{
	  switch (map[i][j])
	    {
	    case CHAR_WALL:
	      t = IGraphicLibrary::WALL;
	      img = IGraphicLibrary::IMG_WALL;
	      break;
	    default:
	      t = IGraphicLibrary::EMPTY;
	      if (i % 2 == 0)
		{
		  if (j % 2 == 0)
		    img = IGraphicLibrary::IMG_EMPTY_1;
		  else
		    img = IGraphicLibrary::IMG_EMPTY_2;
		}
	      else
		{
		  if (j % 2 == 0)
		    img = IGraphicLibrary::IMG_EMPTY_3;
		  else
		    img = IGraphicLibrary::IMG_EMPTY_4;
		}
	      break;
	    }
	  m_map[i].push_back(new Case(i, j, t, img));
	}
    }
}

Game::~Game(void)
{
  for (unsigned int i = 0; i < m_map.size(); i++)
    {
      for (unsigned int j = 0; j < m_map[i].size(); j++)
	{
	  delete m_map[i][j];
	}
    }
}

void		Game::play(void)
{
  m_quit = false;
  m_pause = false;
  m_endOfGame = false;

  while (!m_endOfGame)
    {
      checkEvent();
      if (m_quit)
	{
	  return ;
	}
      if (!m_pause)
	{
	  moveGame();
	  if (m_bonus.checkSnakePosition(m_frame, m_score, m_map, m_snake))
	    {
	      m_endOfGame = true;
	    }
	  checkEndOfGame();
	  display();
	}
      timePause();
    }
}

void		Game::checkEvent(void)
{
  IGraphicLibrary::e_TypeOfEvent	e;

  while ((e = m_graph.checkEvent()) != IGraphicLibrary::NONE)
    {
      if (e == IGraphicLibrary::PAUSE)
	m_pause = !m_pause;
      else if (e == IGraphicLibrary::EXIT)
	{
	  m_quit = true;
	  return ;
	}
      else if (!m_pause && 
	       (e == IGraphicLibrary::KB_UP || e == IGraphicLibrary::KB_DOWN ||
		e == IGraphicLibrary::KB_LEFT || e == IGraphicLibrary::KB_RIGHT))
	{
	  m_snake.setDirection((IGraphicLibrary::e_Direction)(e));
	}
    }
}

void		Game::moveGame(void)
{
  m_snake.move(m_frame, m_score.getVitesse(), m_map);
  m_bonus.move(m_frame, m_map, m_snake);
}

void		Game::checkEndOfGame(void)
{
  if (m_endOfGame == false && m_snake.checkEndOfGame(m_map))
    {
      if (m_score.loseLife() == 0)
	{
	  m_endOfGame = true;
	}
      else
	{
	  m_snake.newSnake(m_size_x / 2, m_size_y / 2, 4);
	}
    }
}

void		Game::display(void)
{
  if (!m_endOfGame)
    {
      for (unsigned int i = 0; i < m_map.size(); i++)
	{
	  for (unsigned int j = 0; j < m_map[i].size(); j++)
	    {
	      m_map[i][j]->draw(m_graph);
	    }
	}
      m_bonus.draw(m_frame, m_graph);
      m_snake.draw(m_graph);
      m_score.draw(m_graph);
      m_graph.refreshScreen();
    }
}

void		Game::timePause(void)
{
  if (!m_endOfGame)
    {
      usleep(TIME_SLEEP);
      m_frame++;
    }
}
